package cn.ug.activity.service.impl;

import cn.ug.activity.bean.ChannelBean;
import cn.ug.activity.bean.ChannelStatisticsBean;
import cn.ug.activity.bean.FundsRecordBean;
import cn.ug.activity.mapper.*;
import cn.ug.activity.mapper.entity.*;
import cn.ug.activity.service.ChannelService;
import cn.ug.bean.base.SerializeObject;
import cn.ug.feign.MemberUserService;
import cn.ug.member.bean.response.MemberUserBean;
import cn.ug.util.RedisConstantUtil;
import cn.ug.util.UF;
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.ug.util.ConstantUtil.MAX_TIME;
import static cn.ug.util.ConstantUtil.MIN_TIME;

@Service
public class ChannelServiceImpl implements ChannelService {
    @Autowired
    private ChannelMapper channelMapper;
    @Autowired
    private DozerBeanMapper dozerBeanMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ChannelViewMapper channelViewMapper;
    @Autowired
    private CouponChannelMapper couponChannelMapper;
    @Autowired
    private MemberUserService memberUserService;
    @Autowired
    private CouponRepertoryMapper couponRepertoryMapper;
    @Autowired
    private CouponMemberMapper couponMemberMapper;

    @Override
    public boolean save(ChannelBean entityBean) {
        if (entityBean != null) {
            Channel entity = dozerBeanMapper.map(entityBean, Channel.class);
            if (StringUtils.isBlank(entityBean.getId())) {
                entity.setId(UF.getRandomUUID());
                entity.setAddTime(LocalDateTime.now());
                entity.setCode(getChannelCode());
                return channelMapper.insert(entity) > 0 ? true : false;
            } else {
                entity.setModifyTime(LocalDateTime.now());
                return channelMapper.update(entity) > 0 ? true : false;
            }
        }
        return false;
    }

    private String getChannelCode() {
        String key = RedisConstantUtil.CHANNEL_CODE_KEY;
        String code = stringRedisTemplate.opsForValue().get(key);
        String channelCode = "";
        if (StringUtils.isBlank(code)) {
            channelCode = String.valueOf(1000020);
            stringRedisTemplate.opsForValue().set(key, channelCode);
        } else {
            long value = Long.parseLong(code);
            value++;
            channelCode = String.valueOf(value);
            stringRedisTemplate.opsForValue().set(key, channelCode);
        }
        return channelCode;
    }

    @Override
    public boolean remove(String id) {
        if (StringUtils.isNoneBlank(id)) {
            return channelMapper.delete(id) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public boolean removeInBatch(String[] id) {
        if (id != null && id.length > 0) {
            return channelMapper.deleteByIds(id) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public ChannelBean get(String id) {
        if (StringUtils.isNoneBlank(id)) {
            Channel entity = channelMapper.findById(id);
            if (entity == null) {
                return null;
            }
            ChannelBean entityBean = dozerBeanMapper.map(entity, ChannelBean.class);
            if (entity.getAddTime() != null) {
                entityBean.setAddTimeString(UF.getFormatDateTime(entity.getAddTime()));
            }
            if (entity.getModifyTime() != null) {
                entityBean.setModifyTimeString(UF.getFormatDateTime(entity.getModifyTime()));
            }
            return entityBean;
        }
        return null;
    }

    @Override
    public List<ChannelBean> listRecords(String name, int offset, int size) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        params.put("offset", offset);
        params.put("size", size);
        List<ChannelBean> data = new ArrayList<ChannelBean>();
        List<Channel> list = channelMapper.query(params);
        if (list == null || list.size() == 0) {
            return null;
        }
        for (Channel entity : list) {
            ChannelBean bean = dozerBeanMapper.map(entity, ChannelBean.class);
            if (entity.getAddTime() != null) {
                bean.setAddTimeString(UF.getFormatDateTime(entity.getAddTime()));
            }
            if (entity.getModifyTime() != null) {
                bean.setModifyTimeString(UF.getFormatDateTime(entity.getModifyTime()));
            }
            data.add(bean);
        }
        return data;
    }

    @Override
    public int countRecords(String name) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        return channelMapper.count(params);
    }

    @Override
    public List<ChannelStatisticsBean> listRecords(String startDate, String endDate, int offset, int size) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("startDate", startDate);
        params.put("endDate", endDate);
        params.put("offset", offset);
        params.put("size", size);
        return channelMapper.channelStatistics(params);
    }

    @Override
    public List<FundsRecordBean> listFundsRecords(int tradeType, String startDate, String endDate, int offset, int size) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("tradeType", tradeType);
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            params.put("startDate", startDate+MIN_TIME);
            params.put("endDate", endDate+MAX_TIME);
        }
        params.put("offset", offset);
        params.put("size", size);
        return channelMapper.queryFundsRecordForList(params);
    }

    @Override
    public int countFundsRecords(int tradeType, String startDate, String endDate) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("tradeType", tradeType);
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            params.put("startDate", startDate+MIN_TIME);
            params.put("endDate", endDate+MAX_TIME);
        }
        return channelMapper.queryFundsRecordForCount(params);
    }

    @Override
    public boolean saveChannelView(ChannelView channelView) {
        if (channelView != null) {
            return channelViewMapper.insert(channelView) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public CouponChannel getCouponChannel(String orderNO) {
        if (StringUtils.isNotBlank(orderNO)) {
            return couponChannelMapper.findByOrderNO(orderNO);
        }
        return null;
    }

    @Override
    public boolean save(CouponChannel couponChannel) {
        if (couponChannel != null && StringUtils.isNotBlank(couponChannel.getMobile())) {
            CouponRepertory coupon = couponRepertoryMapper.findById(couponChannel.getCouponId());
            if (coupon == null) {
                return false;
            }
            double couponAmount = 0;
            /*if (coupon.getType() == 2) {
                String[] amounts = StringUtils.split(coupon.getAmount(), ConstantUtil.MINUS);
                if (amounts != null && amounts.length == 2) {
                    try {
                        int amount = ThreadLocalRandom.current().nextInt(Integer.parseInt(amounts[0]), Integer.parseInt(amounts[1]));
                        couponAmount = amount;
                    } catch (Exception e) {
                    }
                }
            } else {
                couponAmount = Double.parseDouble(coupon.getAmount());
            }*/

            SerializeObject<MemberUserBean> memberUserBean = memberUserService.findByLoginName(couponChannel.getMobile());
            if (memberUserBean != null && memberUserBean.getData() != null) {
                CouponMember couponMember = new CouponMember();
                couponMember.setMemberId(memberUserBean.getData().getId());
                couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                couponMember.setCouponId(coupon.getId());

                couponChannel.setCouponAmount(new BigDecimal(couponAmount));
                couponChannel.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                couponChannelMapper.insert(couponChannel);

                return couponMemberMapper.insert(couponMember) > 0 ? true : false;
            } else {
                couponChannel.setCouponAmount(new BigDecimal(couponAmount));
                couponChannel.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                return couponChannelMapper.insert(couponChannel) > 0 ? true : false;
            }
        }
        return true;
    }
}
